GtkScrollType type);
static void gtk_menu_stop_navigating_submenu (GtkMenu *menu);
-static gboolean gtk_menu_stop_navigating_submenu_cb (gpointer user_data);
static gboolean gtk_menu_navigating_submenu (GtkMenu *menu,
gint event_x,
gint event_y);
-static void gtk_menu_set_submenu_navigation_region (GtkMenu *menu,
- GtkMenuItem *menu_item,
- GdkEventCrossing *event);
-
+
static void gtk_menu_deactivate (GtkMenuShell *menu_shell);
static void gtk_menu_position (GtkMenu *menu,
gboolean set_scroll_offset);
switch (event->type)
{
- case GDK_KEY_PRESS:
- case GDK_KEY_RELEASE:
- handled = gtk_widget_event (menu, event);
- break;
case GDK_WINDOW_STATE:
/* Window for the menu has been closed by the display server or by GDK.
* Update the internal state as if the user had clicked outside the
GtkWidget *parent;
GdkDevice *source_device;
- gboolean need_enter;
-
source_device = gdk_event_get_source_device ((GdkEvent *) event);
if (GTK_IS_MENU (widget) &&
if (definitely_within_item (menu_item, event->x, event->y))
menu_shell->priv->activate_time = 0;
- need_enter = (gtk_menu_has_navigation_triangle (menu) || menu_shell->priv->ignore_enter);
-
/* Check to see if we are within an active submenu's navigation region
*/
if (gtk_menu_navigating_submenu (menu, event->x_root, event->y_root))
return FALSE;
}
- if (need_enter)
- {
- /* The menu is now sensitive to enter events on its items, but
- * was previously sensitive. So we fake an enter event.
- */
- menu_shell->priv->ignore_enter = FALSE;
-
- if (event->x >= 0 && event->x < gdk_window_get_width (event->window) &&
- event->y >= 0 && event->y < gdk_window_get_height (event->window))
- {
- GdkEvent *send_event = gdk_event_new (GDK_ENTER_NOTIFY);
- gboolean result;
-
- send_event->crossing.window = g_object_ref (event->window);
- send_event->crossing.time = event->time;
- send_event->crossing.send_event = TRUE;
- send_event->crossing.x_root = event->x_root;
- send_event->crossing.y_root = event->y_root;
- send_event->crossing.x = event->x;
- send_event->crossing.y = event->y;
- send_event->crossing.state = event->state;
- gdk_event_set_device (send_event, gdk_event_get_device ((GdkEvent *) event));
-
- /* We send the event to 'widget', the currently active menu,
- * instead of 'menu', the menu that the pointer is in. This
- * will ensure that the event will be ignored unless the
- * menuitem is a child of the active menu or some parent
- * menu of the active menu.
- */
- result = gtk_widget_event (widget, send_event);
- gdk_event_free (send_event);
-
- return result;
- }
- }
-
return FALSE;
}
gtk_menu_enter_notify (GtkWidget *widget,
GdkEventCrossing *event)
{
- GtkWidget *menu_item;
- GtkWidget *parent;
GdkDevice *source_device;
if (event->mode == GDK_CROSSING_GTK_GRAB ||
return TRUE;
source_device = gdk_event_get_source_device ((GdkEvent *) event);
- menu_item = gtk_get_event_widget ((GdkEvent*) event);
- if (GTK_IS_MENU (widget) &&
- gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHSCREEN)
+ if (gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHSCREEN)
{
GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget);
event->x_root, event->y_root, TRUE, TRUE);
}
- if (gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHSCREEN &&
- GTK_IS_MENU_ITEM (menu_item))
- {
- GtkWidget *menu = gtk_widget_get_parent (menu_item);
-
- if (GTK_IS_MENU (menu))
- {
- GtkMenuPrivate *priv = (GTK_MENU (menu))->priv;
- GtkMenuShell *menu_shell = GTK_MENU_SHELL (menu);
-
- if (priv->seen_item_enter)
- {
- /* This is the second enter we see for an item
- * on this menu. This means a release should always
- * mean activate.
- */
- menu_shell->priv->activate_time = 0;
- }
- else if ((event->detail != GDK_NOTIFY_NONLINEAR &&
- event->detail != GDK_NOTIFY_NONLINEAR_VIRTUAL))
- {
- if (definitely_within_item (menu_item, event->x, event->y))
- {
- /* This is an actual user-enter (ie. not a pop-under)
- * In this case, the user must either have entered
- * sufficiently far enough into the item, or he must move
- * far enough away from the enter point. (see
- * gtk_menu_motion_notify())
- */
- menu_shell->priv->activate_time = 0;
- }
- }
-
- priv->seen_item_enter = TRUE;
- }
- }
-
- /* If this is a faked enter (see gtk_menu_motion_notify), 'widget'
- * will not correspond to the event widget's parent. Check to see
- * if we are in the parent's navigation region.
- */
- parent = gtk_widget_get_parent (menu_item);
- if (GTK_IS_MENU_ITEM (menu_item) && GTK_IS_MENU (parent) &&
- gtk_menu_navigating_submenu (GTK_MENU (parent),
- event->x_root, event->y_root))
- return TRUE;
-
- return GTK_WIDGET_CLASS (gtk_menu_parent_class)->enter_notify_event (widget, event);
+ return GDK_EVENT_STOP;
}
static gboolean
gtk_menu_leave_notify (GtkWidget *widget,
GdkEventCrossing *event)
{
- GtkMenuShell *menu_shell;
GtkMenu *menu;
- GtkMenuItem *menu_item;
- GtkWidget *event_widget;
GdkDevice *source_device;
if (event->mode == GDK_CROSSING_GTK_GRAB ||
return TRUE;
menu = GTK_MENU (widget);
- menu_shell = GTK_MENU_SHELL (widget);
if (gtk_menu_navigating_submenu (menu, event->x_root, event->y_root))
return TRUE;
if (gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHSCREEN)
gtk_menu_handle_scrolling (menu, event->x_root, event->y_root, FALSE, TRUE);
- event_widget = gtk_get_event_widget ((GdkEvent*) event);
-
- if (!GTK_IS_MENU_ITEM (event_widget))
- return TRUE;
-
- menu_item = GTK_MENU_ITEM (event_widget);
-
- /* Here we check to see if we're leaving an active menu item
- * with a submenu, in which case we enter submenu navigation mode.
- */
- if (menu_shell->priv->active_menu_item != NULL
- && menu_item->priv->submenu != NULL
- && menu_item->priv->submenu_placement == GTK_LEFT_RIGHT)
- {
- if (GTK_MENU_SHELL (menu_item->priv->submenu)->priv->active)
- {
- gtk_menu_set_submenu_navigation_region (menu, menu_item, event);
- return TRUE;
- }
- else if (menu_item == GTK_MENU_ITEM (menu_shell->priv->active_menu_item))
- {
- /* We are leaving an active menu item with nonactive submenu.
- * Deselect it so we don't surprise the user with by popping
- * up a submenu _after_ he left the item.
- */
- gtk_menu_shell_deselect (menu_shell);
- return TRUE;
- }
- }
-
- return GTK_WIDGET_CLASS (gtk_menu_parent_class)->leave_notify_event (widget, event);
+ return GDK_EVENT_STOP;
}
static gboolean
}
}
-/* When the timeout is elapsed, the navigation region is destroyed
- * and the menuitem under the pointer (if any) is selected.
- */
-static gboolean
-gtk_menu_stop_navigating_submenu_cb (gpointer user_data)
-{
- GtkMenuPopdownData *popdown_data = user_data;
- GtkMenu *menu = popdown_data->menu;
- GtkMenuPrivate *priv = menu->priv;
- GdkWindow *child_window;
-
- gtk_menu_stop_navigating_submenu (menu);
-
- if (gtk_widget_get_realized (GTK_WIDGET (menu)))
- {
- child_window = gdk_window_get_device_position (priv->bin_window,
- popdown_data->device,
- NULL, NULL, NULL);
-
- if (child_window)
- {
- GdkEvent *send_event = gdk_event_new (GDK_ENTER_NOTIFY);
-
- send_event->crossing.window = g_object_ref (child_window);
- send_event->crossing.time = GDK_CURRENT_TIME; /* Bogus */
- send_event->crossing.send_event = TRUE;
- gdk_event_set_device (send_event, popdown_data->device);
-
- GTK_WIDGET_CLASS (gtk_menu_parent_class)->enter_notify_event (GTK_WIDGET (menu), (GdkEventCrossing *)send_event);
-
- gdk_event_free (send_event);
- }
- }
-
- return FALSE;
-}
-
static gboolean
gtk_menu_navigating_submenu (GtkMenu *menu,
gint event_x,
}
}
-static void
-gtk_menu_set_submenu_navigation_region (GtkMenu *menu,
- GtkMenuItem *menu_item,
- GdkEventCrossing *event)
-{
- GtkMenuPrivate *priv = menu->priv;
- gint submenu_left = 0;
- gint submenu_right = 0;
- gint submenu_top = 0;
- gint submenu_bottom = 0;
- gint width = 0;
- GtkWidget *event_widget;
- GtkMenuPopdownData *popdown_data;
- GdkWindow *window;
-
- g_return_if_fail (menu_item->priv->submenu != NULL);
- g_return_if_fail (event != NULL);
-
- event_widget = gtk_get_event_widget ((GdkEvent*) event);
-
- window = gtk_widget_get_window (menu_item->priv->submenu);
- gdk_window_get_origin (window, &submenu_left, &submenu_top);
-
- submenu_right = submenu_left + gdk_window_get_width (window);
- submenu_bottom = submenu_top + gdk_window_get_height (window);
-
- width = gdk_window_get_width (gtk_widget_get_window (event_widget));
-
- if (event->x >= 0 && event->x < width)
- {
- gtk_menu_stop_navigating_submenu (menu);
-
- /* The navigation region is the triangle closest to the x/y
- * location of the rectangle. This is why the width or height
- * can be negative.
- */
- if (menu_item->priv->submenu_direction == GTK_DIRECTION_RIGHT)
- {
- /* right */
- priv->navigation_x = submenu_left;
- priv->navigation_width = event->x_root - submenu_left;
- }
- else
- {
- /* left */
- priv->navigation_x = submenu_right;
- priv->navigation_width = event->x_root - submenu_right;
- }
-
- if (event->y < 0)
- {
- /* top */
- priv->navigation_y = event->y_root;
- priv->navigation_height = submenu_top - event->y_root - NAVIGATION_REGION_OVERSHOOT;
-
- if (priv->navigation_height >= 0)
- return;
- }
- else
- {
- /* bottom */
- priv->navigation_y = event->y_root;
- priv->navigation_height = submenu_bottom - event->y_root + NAVIGATION_REGION_OVERSHOOT;
-
- if (priv->navigation_height <= 0)
- return;
- }
-
- popdown_data = g_new (GtkMenuPopdownData, 1);
- popdown_data->menu = menu;
- popdown_data->device = gdk_event_get_device ((GdkEvent *) event);
-
- priv->navigation_timeout = gdk_threads_add_timeout_full (G_PRIORITY_DEFAULT,
- MENU_POPDOWN_DELAY,
- gtk_menu_stop_navigating_submenu_cb,
- popdown_data,
- (GDestroyNotify) g_free);
- g_source_set_name_by_id (priv->navigation_timeout, "[gtk+] gtk_menu_stop_navigating_submenu_cb");
- }
-}
-
static void
gtk_menu_deactivate (GtkMenuShell *menu_shell)
{
GdkEventButton *event);
static gint gtk_menu_shell_key_press (GtkWidget *widget,
GdkEventKey *event);
-static gint gtk_menu_shell_enter_notify (GtkWidget *widget,
- GdkEventCrossing *event);
-static gint gtk_menu_shell_leave_notify (GtkWidget *widget,
- GdkEventCrossing *event);
static void gtk_menu_shell_screen_changed (GtkWidget *widget,
GdkScreen *previous_screen);
static gboolean gtk_menu_shell_grab_broken (GtkWidget *widget,
GtkWidget *child,
gint position);
static void gtk_real_menu_shell_deactivate (GtkMenuShell *menu_shell);
-static gint gtk_menu_shell_is_item (GtkMenuShell *menu_shell,
- GtkWidget *child);
-static GtkWidget *gtk_menu_shell_get_item (GtkMenuShell *menu_shell,
- GdkEvent *event);
static GType gtk_menu_shell_child_type (GtkContainer *container);
static void gtk_menu_shell_real_select_item (GtkMenuShell *menu_shell,
GtkWidget *menu_item);
widget_class->button_release_event = gtk_menu_shell_button_release;
widget_class->grab_broken_event = gtk_menu_shell_grab_broken;
widget_class->key_press_event = gtk_menu_shell_key_press;
- widget_class->enter_notify_event = gtk_menu_shell_enter_notify;
- widget_class->leave_notify_event = gtk_menu_shell_leave_notify;
widget_class->screen_changed = gtk_menu_shell_screen_changed;
container_class->add = gtk_menu_shell_add;
}
}
+static void
+gtk_menu_shell_deactivate_and_emit_done (GtkMenuShell *menu_shell)
+{
+ gtk_menu_shell_deactivate (menu_shell);
+ g_signal_emit (menu_shell, menu_shell_signals[SELECTION_DONE], 0);
+}
+
+static GtkMenuShell *
+gtk_menu_shell_get_toplevel_shell (GtkMenuShell *menu_shell)
+{
+ while (menu_shell->priv->parent_menu_shell)
+ menu_shell = GTK_MENU_SHELL (menu_shell->priv->parent_menu_shell);
+
+ return menu_shell;
+}
+
static gint
gtk_menu_shell_button_press (GtkWidget *widget,
GdkEventButton *event)
GtkMenuShell *menu_shell;
GtkMenuShellPrivate *priv;
GtkWidget *menu_item;
- GtkWidget *parent;
-
- if (event->type != GDK_BUTTON_PRESS)
- return FALSE;
menu_shell = GTK_MENU_SHELL (widget);
priv = menu_shell->priv;
- if (priv->parent_menu_shell)
- return gtk_widget_event (priv->parent_menu_shell, (GdkEvent*) event);
-
- menu_item = gtk_menu_shell_get_item (menu_shell, (GdkEvent *)event);
+ menu_shell = GTK_MENU_SHELL (widget);
+ priv = menu_shell->priv;
+ menu_item = gtk_get_event_target_with_type ((GdkEvent *) event, GTK_TYPE_MENU_ITEM);
- if (menu_item && _gtk_menu_item_is_selectable (menu_item))
+ if (menu_item &&
+ _gtk_menu_item_is_selectable (menu_item) &&
+ gtk_widget_get_parent (menu_item) == widget)
{
- parent = gtk_widget_get_parent (menu_item);
-
- if (menu_item != GTK_MENU_SHELL (parent)->priv->active_menu_item)
+ if (menu_item != menu_shell->priv->active_menu_item)
{
/* select the menu item *before* activating the shell, so submenus
* which might be open are closed the friendly way. If we activate
* menu item also fixes up the state as if enter_notify() would
* have run before (which normally selects the item).
*/
- if (GTK_MENU_SHELL_GET_CLASS (parent)->submenu_placement != GTK_TOP_BOTTOM)
- gtk_menu_shell_select_item (GTK_MENU_SHELL (parent), menu_item);
+ if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM)
+ gtk_menu_shell_select_item (menu_shell, menu_item);
+ }
+
+ if (GTK_MENU_ITEM (menu_item)->priv->submenu != NULL &&
+ !gtk_widget_get_visible (GTK_MENU_ITEM (menu_item)->priv->submenu))
+ {
+ _gtk_menu_item_popup_submenu (menu_item, FALSE);
+ priv->activated_submenu = TRUE;
}
}
menu_item != priv->active_menu_item)
{
gtk_menu_shell_activate (menu_shell);
- priv->button = event->button;
if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM)
{
}
}
}
- else
- {
- if (!initially_active)
- {
- gtk_menu_shell_deactivate (menu_shell);
- return FALSE;
- }
- }
- }
- else
- {
- widget = gtk_get_event_widget ((GdkEvent*) event);
- if (widget == GTK_WIDGET (menu_shell))
+ else if (!initially_active)
{
gtk_menu_shell_deactivate (menu_shell);
- g_signal_emit (menu_shell, menu_shell_signals[SELECTION_DONE], 0);
+ return FALSE;
}
}
- if (menu_item &&
- _gtk_menu_item_is_selectable (menu_item) &&
- GTK_MENU_ITEM (menu_item)->priv->submenu != NULL &&
- !gtk_widget_get_visible (GTK_MENU_ITEM (menu_item)->priv->submenu))
- {
- _gtk_menu_item_popup_submenu (menu_item, FALSE);
- priv->activated_submenu = TRUE;
- }
-
return TRUE;
}
{
/* Unset the active menu item so gtk_menu_popdown() doesn't see it. */
gtk_menu_shell_deselect (menu_shell);
- gtk_menu_shell_deactivate (menu_shell);
- g_signal_emit (menu_shell, menu_shell_signals[SELECTION_DONE], 0);
+ gtk_menu_shell_deactivate_and_emit_done (menu_shell);
}
return TRUE;
{
GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget);
GtkMenuShellPrivate *priv = menu_shell->priv;
+ GtkMenuShell *parent_shell = GTK_MENU_SHELL (priv->parent_menu_shell);
+ gboolean activated_submenu = FALSE;
+
+ if (parent_shell)
+ {
+ /* If a submenu was just activated, it is its shell which is receiving
+ * the button release event. In this case, we must check the parent
+ * shell to know about the submenu state.
+ */
+ activated_submenu = parent_shell->priv->activated_submenu;
+ parent_shell->priv->activated_submenu = FALSE;
+ }
if (priv->parent_menu_shell &&
(event->time - GTK_MENU_SHELL (priv->parent_menu_shell)->priv->activate_time) < MENU_SHELL_TIMEOUT)
* https://bugzilla.gnome.org/show_bug.cgi?id=703069
*/
GTK_MENU_SHELL (priv->parent_menu_shell)->priv->activate_time = 0;
- return TRUE;
+ return GDK_EVENT_STOP;
}
if (priv->active)
{
GtkWidget *menu_item;
- gboolean deactivate = TRUE;
-
- if (priv->button && (event->button != priv->button))
- {
- priv->button = 0;
- if (priv->parent_menu_shell)
- return gtk_widget_event (priv->parent_menu_shell, (GdkEvent*) event);
- }
+ gint button = priv->button;
priv->button = 0;
- menu_item = gtk_menu_shell_get_item (menu_shell, (GdkEvent*) event);
- if ((event->time - priv->activate_time) > MENU_SHELL_TIMEOUT)
+ if (button && (event->button != button) && priv->parent_menu_shell)
{
- if (menu_item && (priv->active_menu_item == menu_item) &&
- _gtk_menu_item_is_selectable (menu_item))
- {
- GtkWidget *submenu = GTK_MENU_ITEM (menu_item)->priv->submenu;
-
- if (submenu == NULL)
- {
- gtk_menu_shell_activate_item (menu_shell, menu_item, TRUE);
- deactivate = FALSE;
- }
- else if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM ||
- priv->activated_submenu)
- {
- GTimeVal *popup_time;
- gint64 usec_since_popup = 0;
-
- popup_time = g_object_get_data (G_OBJECT (submenu),
- "gtk-menu-exact-popup-time");
-
- if (popup_time)
- {
- GTimeVal current_time;
-
- g_get_current_time (¤t_time);
-
- usec_since_popup = ((gint64) current_time.tv_sec * 1000 * 1000 +
- (gint64) current_time.tv_usec -
- (gint64) popup_time->tv_sec * 1000 * 1000 -
- (gint64) popup_time->tv_usec);
-
- g_object_set_data (G_OBJECT (submenu),
- "gtk-menu-exact-popup-time", NULL);
- }
-
- /* Only close the submenu on click if we opened the
- * menu explicitly (usec_since_popup == 0) or
- * enough time has passed since it was opened by
- * GtkMenuItem's timeout (usec_since_popup > delay).
- */
- if (!priv->activated_submenu &&
- (usec_since_popup == 0 ||
- usec_since_popup > MENU_POPDOWN_DELAY * 1000))
- {
- _gtk_menu_item_popdown_submenu (menu_item);
- }
- else
- {
- gtk_menu_item_select (GTK_MENU_ITEM (menu_item));
- }
-
- deactivate = FALSE;
- }
- }
- else if (menu_item &&
- !_gtk_menu_item_is_selectable (menu_item) &&
- GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM)
- {
- deactivate = FALSE;
- }
- else if (priv->parent_menu_shell)
- {
- priv->active = TRUE;
- gtk_widget_event (priv->parent_menu_shell, (GdkEvent*) event);
- deactivate = FALSE;
- }
-
- /* If we ended up on an item with a submenu, leave the menu up. */
- if (menu_item &&
- (priv->active_menu_item == menu_item) &&
- GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM)
- {
- deactivate = FALSE;
- }
+ gtk_menu_shell_deactivate_and_emit_done (gtk_menu_shell_get_toplevel_shell (menu_shell));
+ return GDK_EVENT_STOP;
}
- else /* a very fast press-release */
+
+ if ((event->time - priv->activate_time) <= MENU_SHELL_TIMEOUT)
{
/* We only ever want to prevent deactivation on the first
* press/release. Setting the time to zero is a bit of a
* serious harm if we lose.
*/
priv->activate_time = 0;
- deactivate = FALSE;
+ return GDK_EVENT_STOP;
}
- if (deactivate)
+ menu_item = gtk_get_event_target_with_type ((GdkEvent *) event, GTK_TYPE_MENU_ITEM);
+
+ if (menu_item)
{
- gtk_menu_shell_deactivate (menu_shell);
- g_signal_emit (menu_shell, menu_shell_signals[SELECTION_DONE], 0);
+ GtkWidget *submenu = GTK_MENU_ITEM (menu_item)->priv->submenu;
+ GtkWidget *parent_menu_item_shell = gtk_widget_get_parent (menu_item);
+
+ if (!_gtk_menu_item_is_selectable (GTK_WIDGET (menu_item)))
+ return GDK_EVENT_STOP;
+
+ if (submenu == NULL)
+ {
+ gtk_menu_shell_activate_item (menu_shell, GTK_WIDGET (menu_item), TRUE);
+ return GDK_EVENT_STOP;
+ }
+ else if (GTK_MENU_SHELL (parent_menu_item_shell)->priv->parent_menu_shell &&
+ (activated_submenu ||
+ GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM))
+ {
+ GTimeVal *popup_time;
+ gint64 usec_since_popup = 0;
+
+ popup_time = g_object_get_data (G_OBJECT (menu_shell),
+ "gtk-menu-exact-popup-time");
+ if (popup_time)
+ {
+ GTimeVal current_time;
+
+ g_get_current_time (¤t_time);
+
+ usec_since_popup = ((gint64) current_time.tv_sec * 1000 * 1000 +
+ (gint64) current_time.tv_usec -
+ (gint64) popup_time->tv_sec * 1000 * 1000 -
+ (gint64) popup_time->tv_usec);
+
+ g_object_set_data (G_OBJECT (menu_shell),
+ "gtk-menu-exact-popup-time", NULL);
+ }
+
+ /* Only close the submenu on click if we opened the
+ * menu explicitly (usec_since_popup == 0) or
+ * enough time has passed since it was opened by
+ * GtkMenuItem's timeout (usec_since_popup > delay).
+ */
+ if (!activated_submenu &&
+ (usec_since_popup == 0 ||
+ usec_since_popup > MENU_POPDOWN_DELAY * 1000))
+ {
+ _gtk_menu_item_popdown_submenu (menu_item);
+ }
+ else
+ {
+ gtk_menu_item_select (GTK_MENU_ITEM (menu_item));
+ }
+
+ return GDK_EVENT_STOP;
+ }
}
- priv->activated_submenu = FALSE;
+ gtk_menu_shell_deactivate_and_emit_done (gtk_menu_shell_get_toplevel_shell (menu_shell));
}
- return TRUE;
+ return GDK_EVENT_STOP;
}
void
return gtk_menu_shell_activate_mnemonic (menu_shell, event);
}
-static gint
-gtk_menu_shell_enter_notify (GtkWidget *widget,
- GdkEventCrossing *event)
-{
- GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget);
- GtkMenuShellPrivate *priv = menu_shell->priv;
-
- if (event->mode == GDK_CROSSING_GTK_GRAB ||
- event->mode == GDK_CROSSING_GTK_UNGRAB ||
- event->mode == GDK_CROSSING_STATE_CHANGED)
- return TRUE;
-
- if (priv->active)
- {
- GtkWidget *menu_item;
- GtkWidget *parent;
-
- menu_item = gtk_get_event_widget ((GdkEvent*) event);
-
- if (!menu_item)
- return TRUE;
-
- if (GTK_IS_MENU_ITEM (menu_item) &&
- !_gtk_menu_item_is_selectable (menu_item))
- {
- priv->in_unselectable_item = TRUE;
- return TRUE;
- }
-
- parent = gtk_widget_get_parent (menu_item);
- if (parent == widget &&
- GTK_IS_MENU_ITEM (menu_item))
- {
- if (priv->ignore_enter)
- return TRUE;
-
- if (event->detail != GDK_NOTIFY_INFERIOR)
- {
- if ((gtk_widget_get_state_flags (menu_item) & GTK_STATE_FLAG_PRELIGHT) == 0)
- gtk_menu_shell_select_item (menu_shell, menu_item);
-
- /* If any mouse button is down, and there is a submenu
- * that is not yet visible, activate it. It's sufficient
- * to check for any button's mask (not only the one
- * matching menu_shell->button), because there is no
- * situation a mouse button could be pressed while
- * entering a menu item where we wouldn't want to show
- * its submenu.
- */
- if ((event->state & (GDK_BUTTON1_MASK|GDK_BUTTON2_MASK|GDK_BUTTON3_MASK)) &&
- GTK_MENU_ITEM (menu_item)->priv->submenu != NULL)
- {
- GTK_MENU_SHELL (parent)->priv->activated_submenu = TRUE;
-
- if (!gtk_widget_get_visible (GTK_MENU_ITEM (menu_item)->priv->submenu))
- {
- GdkDevice *source_device;
-
- source_device = gdk_event_get_source_device ((GdkEvent *) event);
-
- if (gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN)
- _gtk_menu_item_popup_submenu (menu_item, TRUE);
- }
- }
- }
- }
- else if (priv->parent_menu_shell)
- {
- gtk_widget_event (priv->parent_menu_shell, (GdkEvent*) event);
- }
- }
-
- return TRUE;
-}
-
-static gint
-gtk_menu_shell_leave_notify (GtkWidget *widget,
- GdkEventCrossing *event)
-{
- if (event->mode == GDK_CROSSING_GTK_GRAB ||
- event->mode == GDK_CROSSING_GTK_UNGRAB ||
- event->mode == GDK_CROSSING_STATE_CHANGED)
- return TRUE;
-
- if (gtk_widget_get_visible (widget))
- {
- GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget);
- GtkMenuShellPrivate *priv = menu_shell->priv;
- GtkWidget *event_widget = gtk_get_event_widget ((GdkEvent*) event);
- GtkMenuItem *menu_item;
-
- if (!event_widget || !GTK_IS_MENU_ITEM (event_widget))
- return TRUE;
-
- menu_item = GTK_MENU_ITEM (event_widget);
-
- if (!_gtk_menu_item_is_selectable (event_widget))
- {
- priv->in_unselectable_item = TRUE;
- return TRUE;
- }
-
- if ((priv->active_menu_item == event_widget) &&
- (menu_item->priv->submenu == NULL))
- {
- if ((event->detail != GDK_NOTIFY_INFERIOR) &&
- (gtk_widget_get_state_flags (GTK_WIDGET (menu_item)) & GTK_STATE_FLAG_PRELIGHT) != 0)
- {
- gtk_menu_shell_deselect (menu_shell);
- }
- }
- else if (priv->parent_menu_shell)
- {
- gtk_widget_event (priv->parent_menu_shell, (GdkEvent*) event);
- }
- }
-
- return TRUE;
-}
-
static void
gtk_menu_shell_screen_changed (GtkWidget *widget,
GdkScreen *previous_screen)
}
}
-static gint
-gtk_menu_shell_is_item (GtkMenuShell *menu_shell,
- GtkWidget *child)
-{
- GtkWidget *parent;
-
- g_return_val_if_fail (GTK_IS_MENU_SHELL (menu_shell), FALSE);
- g_return_val_if_fail (child != NULL, FALSE);
-
- parent = gtk_widget_get_parent (child);
- while (GTK_IS_MENU_SHELL (parent))
- {
- if (parent == (GtkWidget*) menu_shell)
- return TRUE;
- parent = GTK_MENU_SHELL (parent)->priv->parent_menu_shell;
- }
-
- return FALSE;
-}
-
-static GtkWidget*
-gtk_menu_shell_get_item (GtkMenuShell *menu_shell,
- GdkEvent *event)
-{
- GtkWidget *menu_item;
-
- menu_item = gtk_get_event_widget ((GdkEvent*) event);
-
- while (menu_item && !GTK_IS_MENU_ITEM (menu_item))
- menu_item = gtk_widget_get_parent (menu_item);
-
- if (menu_item && gtk_menu_shell_is_item (menu_shell, menu_item))
- return menu_item;
- else
- return NULL;
-}
-
/* Handlers for action signals */
/**